package chapter14

import org.apache.spark.sql.{DataFrame, SparkSession}

/**
 * @author: 余辉  
 * @blog: https://blog.csdn.net/silentwolfyh
 * @date: 2024 - 08 - 31 9:28 下午
 * @description:
 * 需求：
 * 1、每个人评价最高的10部电影
 * 2、最热门的前50部电影 (被评分的次数说明热门程度）
 * 3、每个人的评分总和
 * 4、每部电影的总得分和平均得分
 * */
object MovieSQL {

  def main(args: Array[String]): Unit = {

    val spark: SparkSession = SparkSession
      .builder()
      .appName("")
      .master("local[*]")
      .getOrCreate()

    val frame: DataFrame = spark
      .read
      .json("doc/exercise/电影评分/rating.json")
      .drop("raete")
    frame.createTempView("t")

    /** *
     * 每个人评价最高的10部电影
     * 1、首先按照用户进行分区 ，按照评分进行排序（降序），且打上便签 ，（窗口函数）
     * 2、只需要获取 rn <11
     *
     * uid    rate  rn
     * uid1   5      1
     * uid1   4      2
     * uid1   4      3
     * uid1   3      4
     * uid1   3      5
     */

    spark.sql(
      """
        |
        |select
        |  uid , movie ,rate,rn
        |from
        |(
        |   select
        |     uid , movie ,rate ,row_number() over(partition by uid order by rate desc) rn
        |   from t
        |) t2
        |where rn < 11
        |
        |""".stripMargin).show()


    /** *
     * 最热门的前50部电影 (被评分的次数说明热门程度）
     * 1、按照电影进行分组，求评分次数
     * 2、将评分次数进行排序（降序）
     */

    spark.sql(
      """
        |
        |select
        |   movie,cs
        |from (
        |		select
        |		movie,count(1) as cs
        |		from t
        |		group by movie
        |) t2
        |order by cs desc
        |
        |""".stripMargin).show()


    /** *
     * 每个人的评分总和
     */

    spark.sql(
      """
        |select
        |  uid,sum(rate)
        |from t group by uid
        |
        |""".stripMargin).show()

    /** *
     * 每部电影的总得分和平均得分
     * 1、按照电影进行分组
     * 2、再在组内进行求sum , avg
     */
    spark.sql(
      """
        |select
        |   movie,sum(rate),avg(rate)
        |from t
        |group by movie
        |
        |""".stripMargin).show()

  }
}
